package cn.h8k.hj212.codec;

import cn.h8k.hj212.entity.Hj212Message;
import cn.h8k.hj212.plugin.MonitoringFactorPlugin;
import cn.h8k.hj212.plugin.PluginManager;
import cn.h8k.hj212.version.ProtocolVersion;
import cn.h8k.hj212.version.VersionAdapter;
import cn.h8k.hj212.version.impl.Hj212_2017_Adapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 增强的HJ212编解码器
 * 集成插件支持、版本适配、性能优化等功能
 * 
 * @author HJ212 Team
 * @since 1.0
 */
public class EnhancedHj212Codec implements Hj212EntityCodec {
    
    private static final Logger logger = LoggerFactory.getLogger(EnhancedHj212Codec.class);
    
    private final PluginManager pluginManager;
    private final Map<ProtocolVersion, VersionAdapter> versionAdapters;
    private final Map<String, Object> codecCache;
    private final boolean enableCache;
    private final boolean enableValidation;
    private final ProtocolVersion defaultVersion;
    
    /**
     * 构造函数
     * @param enableCache 是否启用缓存
     * @param enableValidation 是否启用验证
     * @param defaultVersion 默认协议版本
     */
    public EnhancedHj212Codec(boolean enableCache, boolean enableValidation, ProtocolVersion defaultVersion) {
        this.pluginManager = PluginManager.getInstance();
        this.versionAdapters = new ConcurrentHashMap<>();
        this.codecCache = enableCache ? new ConcurrentHashMap<>() : null;
        this.enableCache = enableCache;
        this.enableValidation = enableValidation;
        this.defaultVersion = defaultVersion != null ? defaultVersion : ProtocolVersion.getDefault();
        
        // 初始化版本适配器
        initializeVersionAdapters();
        
        logger.info("增强HJ212编解码器初始化完成 - 缓存: {}, 验证: {}, 默认版本: {}", 
                   enableCache, enableValidation, this.defaultVersion.getFullName());
    }
    
    /**
     * 默认构造函数
     */
    public EnhancedHj212Codec() {
        this(true, true, ProtocolVersion.getDefault());
    }
    
    @Override
    public String encode(Hj212Message message) {
        if (message == null) {
            throw new IllegalArgumentException("消息不能为空");
        }
        
        try {
            // 检查缓存
            String cacheKey = null;
            if (enableCache) {
                cacheKey = generateCacheKey("encode", message);
                Object cached = codecCache.get(cacheKey);
                if (cached instanceof String) {
                    logger.debug("从缓存获取编码结果");
                    return (String) cached;
                }
            }
            
            // 执行插件验证
            if (enableValidation) {
                validateMessageWithPlugins(message);
            }
            
            // 获取版本适配器
            ProtocolVersion version = detectMessageVersion(message);
            VersionAdapter adapter = getVersionAdapter(version);
            
            // 编码消息
            String result = adapter.formatMessage(message);
            
            // 缓存结果
            if (enableCache && cacheKey != null) {
                codecCache.put(cacheKey, result);
            }
            
            logger.debug("消息编码完成，版本: {}", version.getFullName());
            return result;
            
        } catch (Exception e) {
            logger.error("编码消息失败", e);
            throw new RuntimeException("编码失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public Hj212Message decode(String data) {
        if (data == null || data.trim().isEmpty()) {
            throw new IllegalArgumentException("协议数据不能为空");
        }
        
        try {
            // 检查缓存
            String cacheKey = null;
            if (enableCache) {
                cacheKey = generateCacheKey("decode", data);
                Object cached = codecCache.get(cacheKey);
                if (cached instanceof Hj212Message) {
                    logger.debug("从缓存获取解码结果");
                    return (Hj212Message) cached;
                }
            }
            
            // 检测协议版本
            ProtocolVersion version = detectProtocolVersion(data);
            VersionAdapter adapter = getVersionAdapter(version);
            
            // 验证协议格式
            if (enableValidation) {
                VersionAdapter.ValidationResult validationResult = adapter.validateProtocol(data);
                if (!validationResult.isValid()) {
                    throw new IllegalArgumentException("协议验证失败: " + validationResult.getMessage());
                }
            }
            
            // 解码消息
            Hj212Message result = adapter.parseMessage(data);
            
            // 执行插件验证
            if (enableValidation) {
                validateMessageWithPlugins(result);
            }
            
            // 缓存结果
            if (enableCache && cacheKey != null) {
                codecCache.put(cacheKey, result);
            }
            
            logger.debug("消息解码完成，版本: {}", version.getFullName());
            return result;
            
        } catch (Exception e) {
            logger.error("解码消息失败", e);
            throw new RuntimeException("解码失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 清空缓存
     */
    public void clearCache() {
        if (codecCache != null) {
            codecCache.clear();
            logger.info("编解码器缓存已清空");
        }
    }
    
    /**
     * 获取缓存统计信息
     * @return 缓存统计信息
     */
    public Map<String, Object> getCacheStats() {
        Map<String, Object> stats = new HashMap<>();
        if (codecCache != null) {
            stats.put("enabled", true);
            stats.put("size", codecCache.size());
            stats.put("maxSize", 1000); // 可配置的最大缓存大小
        } else {
            stats.put("enabled", false);
            stats.put("size", 0);
        }
        return stats;
    }
    
    /**
     * 注册版本适配器
     * @param adapter 版本适配器
     */
    public void registerVersionAdapter(VersionAdapter adapter) {
        if (adapter != null) {
            versionAdapters.put(adapter.getSupportedVersion(), adapter);
            logger.info("注册版本适配器: {}", adapter.getSupportedVersion().getFullName());
        }
    }
    
    /**
     * 检测协议版本
     * @param protocolData 协议数据
     * @return 协议版本
     */
    private ProtocolVersion detectProtocolVersion(String protocolData) {
        // 遍历所有版本适配器，找到兼容的版本
        for (VersionAdapter adapter : versionAdapters.values()) {
            if (adapter.isCompatible(protocolData)) {
                return adapter.getSupportedVersion();
            }
        }
        
        // 如果没有找到兼容的版本，返回默认版本
        logger.warn("未检测到协议版本，使用默认版本: {}", defaultVersion.getFullName());
        return defaultVersion;
    }
    
    /**
     * 检测消息版本
     * @param message 消息
     * @return 协议版本
     */
    private ProtocolVersion detectMessageVersion(Hj212Message message) {
        // 可以根据消息内容检测版本，目前返回默认版本
        return defaultVersion;
    }
    
    /**
     * 获取版本适配器
     * @param version 协议版本
     * @return 版本适配器
     */
    private VersionAdapter getVersionAdapter(ProtocolVersion version) {
        VersionAdapter adapter = versionAdapters.get(version);
        if (adapter == null) {
            logger.warn("未找到版本 {} 的适配器，使用默认适配器", version.getFullName());
            adapter = versionAdapters.get(defaultVersion);
        }
        
        if (adapter == null) {
            throw new RuntimeException("未找到可用的版本适配器");
        }
        
        return adapter;
    }
    
    /**
     * 使用插件验证消息
     * @param message 消息
     */
    private void validateMessageWithPlugins(Hj212Message message) {
        if (message == null || message.getData() == null || message.getData().getCpGroups() == null) {
            return;
        }
        
        // 验证CP数据中的监测因子
        message.getData().getCpGroups().forEach(cpGroup -> {
            cpGroup.getItems().forEach(cpItem -> {
                String factorCode = cpItem.getName();
                Object value = cpItem.getValue();
                
                // 使用插件管理器验证监测因子
                MonitoringFactorPlugin.ValidationResult result = 
                    pluginManager.validateFactor(factorCode, value, null);
                
                if (!result.isValid()) {
                    logger.warn("监测因子验证失败: {} - {}", factorCode, result.getMessage());
                    // 可以选择抛出异常或记录警告
                }
            });
        });
    }
    
    /**
     * 生成缓存键
     * @param operation 操作类型
     * @param data 数据
     * @return 缓存键
     */
    private String generateCacheKey(String operation, Object data) {
        return operation + ":" + data.hashCode();
    }
    
    /**
     * 初始化版本适配器
     */
    private void initializeVersionAdapters() {
        // 注册HJ212-2017适配器
        registerVersionAdapter(new Hj212_2017_Adapter());
        
        // 可以在这里注册其他版本的适配器
        logger.info("版本适配器初始化完成，支持版本: {}", versionAdapters.keySet());
    }
}
